package top.jbxie.raft.current;


import java.util.concurrent.*;

/**
 * raft线程池配置
 */
public class RaftThreadPool {
    private static int cup = Runtime.getRuntime().availableProcessors();  // 核心线程数
    private static int maxPoolSize = cup * 2; // 最大线程池大小
    private static final int queueSize = 1024; // 队列长度
    private static final long keepTime = 1000 * 60; // 线程池维护线程所允许的空闲时间，当线程数大于核心时，这是多余空闲线程在终止前等待新任务的最长时间。
    private static TimeUnit keepTimeUnit = TimeUnit.MILLISECONDS; // 时间单位---毫秒

    // ScheduledExecutorService,是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。
    // ScheduledThreadPoolExecutor处理定时任务
    private static ScheduledExecutorService ss = new ScheduledThreadPoolExecutor(cup, new NameThreadFactory());

    //定义线程池
    private static ThreadPoolExecutor te = new RaftThreadPoolExecutor(
            cup,
            maxPoolSize,
            keepTime,
            keepTimeUnit,
            new LinkedBlockingQueue<>(queueSize), //任务队列
            new NameThreadFactory()); // 执行器创建新线程时要使用的工厂

//    private static ThreadPoolExecutor getThreadPool() {
//        return new RaftThreadPoolExecutor(
//                cup,
//                maxPoolSize,
//                keepTime,
//                keepTimeUnit,
//                new LinkedBlockingQueue<>(queueSize),
//                new NameThreadFactory());
//    }

//    private static ScheduledExecutorService getScheduled() {
//        return new ScheduledThreadPoolExecutor(cup, new NameThreadFactory());
//    }

    /**
     * scheduleAtFixedRate每次执行时间为上一次任务开始起向后推一个时间间隔
     * @param r
     * @param initDelay 首次执行任务的延迟时间
     * @param delay 每次执行任务的间隔时间
     */
    public static void scheduleAtFixedRate(Runnable r, long initDelay, long delay) {
        ss.scheduleAtFixedRate(r, initDelay, delay, TimeUnit.MILLISECONDS);
    }

    /**
     * scheduleWithFixedDelay每次执行时间为上一次任务结束起向后推一个时间间隔
     * @param r
     * @param delay
     */
    public static void scheduleWithFixedDelay(Runnable r, long delay) {
        ss.scheduleWithFixedDelay(r, 0, delay, TimeUnit.MILLISECONDS);
    }

    @SuppressWarnings("unchecked")
    public static <T> Future<T> submit(Callable r) {
        return te.submit(r);
    }

    /**
     *  线程提交
     * @param r Runnable接口实现类
     */
    public static void execute(Runnable r) {
        te.execute(r);
    }

    public static void execute(Runnable r, boolean sync) {
        if (sync) {
            r.run();
        } else {
            te.execute(r);
        }
    }

    static class NameThreadFactory implements ThreadFactory {

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new RaftThread("Raft thread", r);
            t.setDaemon(true); //守护线程
            t.setPriority(5); // 优先级
            return t;
        }
    }
}
